package com.zw.mes.util;


import com.zw.mes.constant.Constant;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.*;

/**
 * @Description: 对象比较工具类
 * @Author: China.sgl
 * @Date: 2020/7/30 9:42
 */
@SuppressWarnings("all")
public class BeanUtil {
    /**
     * 复制map对象
     *
     * @param paramsMap 被拷贝对象
     * @param resultMap 拷贝后的对象
     * @explain 将paramsMap中的键值对全部拷贝到resultMap中；
     * paramsMap中的内容不会影响到resultMap（深拷贝）
     */
    public static void mapCopy(Map paramsMap, Map resultMap) {
        if (resultMap == null)
            resultMap = new HashMap();
        if (paramsMap == null) return;

        Iterator it = paramsMap.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            Object key = entry.getKey();
            resultMap.put(key, paramsMap.get(key) != null ? paramsMap.get(key) : "");

        }
    }

    /**
     * 比较对象属性，返回属性值不同的字符串
     *
     * @param before           之前的对象
     * @param after            之后的对象
     * @param ignoreProperties 排除的属性
     * @return 比较后的字符串
     */
    public static String compare(Object before, Object after, String... ignoreProperties) {
        StringBuilder sb = new StringBuilder();
        final BeanWrapper beforeWrapper = new BeanWrapperImpl(before);
        PropertyDescriptor[] beforePds = beforeWrapper.getPropertyDescriptors();
        List<String> ignoreList = ignoreProperties != null ? Arrays.asList(ignoreProperties) : null;
        for (PropertyDescriptor beforePd : beforePds) {
            if (ignoreList == null || !ignoreList.contains(beforePd.getName())) {
                try {
                    PropertyDescriptor afterPd = new PropertyDescriptor(beforePd.getName(), after.getClass());
                    Method beforeMethod = beforePd.getReadMethod();
                    Method afterMethod = afterPd.getReadMethod();
                    Object beforeValue = beforeMethod.invoke(before);
                    Object afterValue = afterMethod.invoke(after);
                    if (beforeValue != null && afterValue != null
                            && !beforeValue.toString().equals(afterValue.toString())
                            && Constant.FIELD_NAME.get(beforePd.getName()) != null) {
                        sb.append(Constant.FIELD_NAME.get(beforePd.getName()))
                                .append("：【")
                                .append(beforeValue)
                                .append("】 -> 【")
                                .append(afterValue)
                                .append("】<br>");
                    }
                } catch (Exception ignored) {
                }
            }
        }
        if (sb.toString().length() == 0) {
            sb.append("-");
        }
        return sb.toString();
    }

    /**
     * 获取对象中属性值为空的属性名称
     *
     * @param obj 对象实例
     * @return 空值的属性名称数组
     */
    public static String[] getNullPropertyNames(Object obj) {
        final BeanWrapper src = new BeanWrapperImpl(obj);
        PropertyDescriptor[] pds = src.getPropertyDescriptors();

        Set<String> emptyNames = new HashSet<>();
        for (PropertyDescriptor pd : pds) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if (srcValue == null) {
                emptyNames.add(pd.getName());
            }
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }

    /**
     * 复制对象，并排除空值属性
     *
     * @param source 源对象
     * @param target 目标对象
     */
    public static void copy(Object source, Object target) {
        BeanUtils.copyProperties(source, target, getNullPropertyNames(source));
    }

}
